﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using InsuranceAdjuster.OccasionallyConnected;
using InsuranceAdjuster.OccasionallyConnected.Messages;
namespace InsuranceAdjuster.ViewModels {
    public class ViewModelBase<T> : ViewModelBase
        where T : IEntity {
        private T _Model = default(T);
        private Guid _EntityGuid = Guid.Empty;

        public ViewModelBase()
            : base() {
            EntityManager.EntityChanged += EntityManager_EntityChanged;
        }


        public new T Model {
            get {
                return _Model;
            }
            set {
                _Model = value;
                this.RaisePropertyChanged("Model");
            }
        }
        public Guid EntityGuid {
            get { return _EntityGuid; }
            private set {
                _EntityGuid = value;
            }
        }


        protected virtual void OnNewModelAvailable(T currentModel, T newerModel) {

        }
        protected virtual void LoadExistingModel(Guid entityGuid) {
            throw new NotImplementedException("Must override LoadExistingModel(Guid)");
        }
        protected virtual void LoadNewModel() {
            throw new NotImplementedException("Must override LoadNewModel()");
        }

        protected override void RaisePropertyChanged(string propertyName) {
            base.RaisePropertyChanged(propertyName);

            switch (propertyName) {
                case "NavigationContext":
                    if (NavigationContext.QueryString.ContainsKey("entityGuid")) {
                        if (NavigationContext.QueryString["entityGuid"].Equals("new", StringComparison.InvariantCultureIgnoreCase)) {
                            LoadNewModel();
                        } else {
                            this.EntityGuid = new Guid(NavigationContext.QueryString["entityGuid"]);
                            LoadExistingModel(EntityGuid);
                        }
                    }
                    break;
            }
        }

        private void EntityManager_EntityChanged(Guid entityGuid, Type entityType, ChangeOperation changeOperation, Origin changeOrigin, IEntity entity) {
            if ((changeOperation == ChangeOperation.Read)
                && Model != null
                && Model.EntityGuid == entityGuid
                && Model.EntityVersion < entity.EntityVersion) {
                OnNewModelAvailable(Model, (T)entity);
            } else if ((changeOperation == ChangeOperation.Read)
                  && Model == null
                  && this.EntityGuid == entityGuid) {
                Model = (T)entity;
                OnNewModelAvailable(default(T), (T)entity);
            }
        }
    }
}
